#include <iostream>
#include <vector>


class Dfs {
 public:
    std::vector<std::vector<int> > *graph;
    std::vector <bool> used;
    Dfs (std::vector<std::vector<int> > *graph):graph(graph) {
        for (int i = 0; i < graph->size(); ++i) {
            used.push_back(false);
        }
    };

    virtual void dfsVisitCurrent (int current, int prev = -1) {
        return;
    }

    virtual void dfsVisitNext (int current, int next) {
        return;
    }

    virtual void dfsWas (int current, int next) {
        return;
    }

    void dfs (int current, int prev = -1) {
        used[current] = true;
        dfsVisitCurrent (current, prev);
        for (auto next_it = 0; next_it < graph->at(current).size(); ++next_it) {
            int next = (graph->at(current))[next_it];
            if (next == prev) {
                continue;
            } else if (used[next]) {
                dfsWas(current, next);
            } else {
                dfs(next, current);
                dfsVisitNext(current, next);
            }
        }
    }
};

class VertexCout : public Dfs {
 public:
    VertexCout (std::vector<std::vector<int> > *graph):Dfs(graph) {

    };

    void dfsVisitCurrent (int current, int prev = -1) {
        std::cout << "entering " << current << " from " << prev << '\n';
    }

    void dfsVisitNext (int current, int next) {
        std::cout << "made Dfs with current: " << current << ", next: " << next << '\n';
    }

    void dfsWas (int current, int next) {
        return;
    }
};

class CountBridges : public Dfs {
 public:
    int timer, answer;
    std::vector<int> time_in, time_back;
    CountBridges (std::vector<std::vector<int> > *graph):Dfs(graph) {
        timer = 0;
        answer = 0;
        for (int i = 0; i < graph->size(); ++i) {
            time_in.push_back(0);
            time_back.push_back(0);
        }
    };

    void dfsVisitCurrent (int current, int prev = -1) {
        std::cout << "entering " << current << " from " << prev << '\n';
        time_in[current] = timer;
        time_back[current] = timer++;
    }

    void dfsVisitNext (int current, int next) {
        time_back[current] = std::min(time_back[current], time_back[next]);
        if (time_in[current] < time_back[next]) {
            answer += 1;
        }
    }

    void dfsWas (int current, int next) {
        time_back[current] = std::min(time_in[next], time_back[current]);
    }
};

int main () {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<int> > graph(n);
    for (int i = 0; i < m; ++i) {
        int x, y;
        std::cin >> x >> y;
        graph[x].push_back(y);
        graph[y].push_back(x);
    }
    CountBridges* pointer = new CountBridges (&graph);
    pointer->dfs(0);
    std::cout << pointer->answer;
    return 0;
}
